// Loesung_von_Aufgabe_10.3_4_Raumkruemmung

float skalierung = 10; // Gibt die Größe einer Gitterzelle an
float rotationX = PI/4; // Rotation um die x-Achse (Startwert entspricht 45°)
float rotationZ = 0; // Rotation um die z-Achse
float positionZ = 0; // Verschiebung entlang der z-Achse
float[][] raumkruemmung = new float[50][50]; // zweidimensionales Array zur Speicherung der Funktionswerte

void setup()
{
  size(750, 750, P3D);
  translate(375, 375);

  // Das zweidimensionale Array wird mit Funktionswerten gefüllt 
  for (int y = 0; y < 50; y++)
  {
    for (int x = 0; x < 50; x++)
    {
      raumkruemmung[x][y] = -100/((pow((x-25), 2) +  pow((y-25), 2) + 20));
    }
  }
}

/* Die folgende Funktion wird aufgerufen, wenn die Maustaste gedrückt ist
 und die Maus bewegt wird */
void mouseDragged() 
{
  /* Die Differenz der Mauskoordinaten (aktuelle Position und vorherige
   Position) wird verkleinert und zur Rotation entlang der x- bzw. z-Achse 
   addiert */
  rotationX += (mouseY - pmouseY) * -0.01;
  rotationZ += (mouseX - pmouseX) * -0.01;
}

// Die folgende Funktion ändert die Werte durch das Drehen des Mausrades
void mouseWheel(MouseEvent event)
{
  // Die Bewegung des Mausrads wird zur Verschiebung entlang der z-Achse addiert
  positionZ += event.getCount() * 100;
}

void draw()
{
  colorMode(RGB, 255, 255, 255); // Farbraum RGB für den Hintergrund
  background(255, 255, 255);
  stroke(0, 0, 0);
  strokeWeight(1);

  translate(width / 2, height / 2, 0); // Die Null dient hier als Hinweis, dass die z-Koordinate nicht verändert wird
  rotateX(rotationX);
  rotateZ(rotationZ);
  translate(0, 0, positionZ); // Das Koordinatensystem kann mit dem Mausrad in z-Richtung verschoben werden

  colorMode(HSB, 360, 100, 100); // Farbraum für die Raumdarstellung

  // Zeichnet den Raum als eine mit Dreiecken dargestellte Oberfläche
  for (int y = 0; y < 50 - 1; y++)
  {
    beginShape(TRIANGLE_STRIP); 
    for (int x = 0; x < 50; x++)
    {    
      // Die Farben werden entsprechend der Funktionsgröße angepasst (HSB)
      fill(raumkruemmung[x][y] * 50 + 180, 100, 100);
      vertex((x - 25) * skalierung, (y - 25) * skalierung, raumkruemmung[x][y] * skalierung); 
      vertex((x - 25) * skalierung, (y - 25 + 1) * skalierung, raumkruemmung[x][y + 1] * skalierung);
    }
    endShape();
  }

  // raumkrümmende Masse
  fill(0);
  sphere(25);
}